﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using System.IO;
using UofCASE.AgileProductLinerDSL.Nant.Tasks.visualizing;


namespace UofCASE.AgileProductLinerDSL.Nant.Tasks
{
    class AspenPlatformVisualizer
    {
        public string ProductLinerDir { get; set; }

        protected void ExecuteTask()
        {
            IList<String> resultFiles = collectFeatureResults();
            Log(Level.Info, "Visualizing " + resultFiles.Count() + " Platforms");
            foreach(String str in resultFiles)Log(Level.Info, "\t"+str);
            if (allExist(resultFiles))
            {

                FeatureResultSet resultSet = new FeatureResultSet();
                foreach (String file in resultFiles)
                {
                    Log(Level.Info, "Reading " + file);
                    resultSet.AddFromXml(File.ReadAllText(file));
                }
                String summaryFile = ProductLinerDir + "/results.html";
                Log(Level.Info, "Writing to " + summaryFile);
                File.WriteAllText(summaryFile, resultSet.ToString());
            }
        }

        private void Log(Level l, String str)
        {

        }

        private bool allExist(IList<string> resultFiles)
        {
            bool allexist = true;
            foreach (String file in resultFiles)
            {
                allexist = allexist && File.Exists(file);
                if (!allexist) break;
            }
            return allexist;
        }

        private IList<string> collectFeatureResults()
        {
            IList<String> results = new List<String>();
            String dir = ProductLinerDir + "/Platforms/";
            String [] platforms = Directory.GetDirectories(dir);
            foreach (String platform in platforms)
            {
                Console.WriteLine("Considering " + platform);
                if (!Path.GetFileName(platform).StartsWith("."))
                {
                    results.Add(platform + "/Results/featureResults.xml");
                    Console.WriteLine("Added " + platform);
                }
            }
            return results;
        }
    }

   

    class FeatureResultSet
    {
        Dictionary<String, IList<FeatureResult>> results = new Dictionary<string, IList<FeatureResult>>();
        HashSet<String> features = new HashSet<String>();
        
        public void AddFromXml(String xml){
            StringReader stringReader = new StringReader(xml);
            System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader(stringReader);
            reader.WhitespaceHandling = System.Xml.WhitespaceHandling.Significant;
            reader.Read();

            String platform = reader.GetAttribute("Platform");
            List<FeatureResult> results = new List<FeatureResult>();
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case (System.Xml.XmlNodeType.Element):
                        FeatureResult result = new FeatureResult(reader.GetAttribute("name"), Boolean.Parse(reader.GetAttribute("passed")));
                        while (reader.Read())
                        {
                            switch (reader.NodeType)
                            {
                                case (System.Xml.XmlNodeType.Element):
                                    FeatureTest test = new FeatureTest( reader.GetAttribute("path"), Boolean.Parse(reader.GetAttribute("passed")) );
                                    result.add(test);
                                    break;
                                default: break;
                            }
                        }
                        results.Add(result);
                        features.Add(result.Feature);
                        break;
                    default: break;
                }
            }
            this.results.Add(platform, results);
        }

        public override String ToString()
        {
            XmlElement table = new XmlElement("table", "border", "1");
            XmlElement headerRow = new XmlElement("tr");
            XmlElement cellx0y0 = new XmlElement("td");
            cellx0y0.AddChildElement(new WhiteSpaceTextElement());
            headerRow.AddChildElement(cellx0y0);
            foreach (String platform in results.Keys)
            {
                XmlElement platformCell = new XmlElement("td");
                platformCell.AddChildElement(new TextElement(platform));
                headerRow.AddChildElement(platformCell);
            }
            

            //feature rows
            foreach (String feature in features)
            {
                XmlElement featureRow = new XmlElement("tr");
                
                XmlElement featureCell = new XmlElement("td");
                XmlElement featureBolding = new XmlElement("b");
                featureBolding.AddChildElement(new TextElement(feature));
                featureCell.AddChildElement(featureBolding);
                featureRow.AddChildElement(featureCell);

                
                foreach (String platform in results.Keys)
                {
                    bool found = false;
                    IList<FeatureResult> resultset = null;
                    results.TryGetValue(platform, out resultset);
                    if (resultset != null)
                    {
                        foreach (FeatureResult result in resultset)
                        {
                            if (result.Feature.Equals(feature))
                            {
                                String style = "background:";
                                if (result.Passed)
                                {
                                    style += "#AAFFAA;";
                                }
                                else
                                {
                                    style += "#FFAAAA;";
                                }
                                
                                XmlElement resultCell = new XmlElement("td", "style", style);
                                resultCell.AddChildElement(new WhiteSpaceTextElement());
                                featureRow.AddChildElement(resultCell);
                                found = true;
                                break;
                            }
                        }
                    }
                    if (!found)
                    {
                        XmlElement emptyCell = new XmlElement("td");
                        emptyCell.AddChildElement(new WhiteSpaceTextElement());
                        featureRow.AddChildElement(emptyCell);
                    }
                }
                
            }
            return table.ToString();
        }

        
    }

    class FeatureResult
    {
        public String Feature { get; set; }
        public bool Passed { get; set; }
        public IList<FeatureTest> Tests { get; set; }

        public FeatureResult(String feature, bool passed)
        {
            Feature = feature;
            Passed = passed;
            Tests = new List<FeatureTest>();
        }

        public void add(FeatureTest test)
        {
            Tests.Add(test);
        }
    }

    class FeatureTest
    {
        public FileInfo resultfile { get; set; }
        public bool Passed { get; set; }

        public FeatureTest(String path, bool passed)
        {
            resultfile = new FileInfo(path);
            Passed = passed;
        }
    }

}

